﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Jzy.Workflow.Line;
using System.Data;

using Jzy.Workflow.Flow;

using Frame.Lib.Core.User;
using Frame.Lib.Core.Role;
using Frame.Lib.Utilities;
using Frame.Lib.Core.Base;
using Frame.Lib.Common;

namespace Jzy.Workflow.Node
{
    public class FlowNodeBO : CommonOperate<FlowNodeInfo>
    {
        private FlowNodeDAL _flowNode;
        protected override BaseDAL DAL
        {
            get
            {
                return _flowNode;
            }
        }
        public FlowNodeBO()
            : base("FlowNode")
        {
            _flowNode = new FlowNodeDAL();
        }
        public override void Delete(int id)
        {
           
            try
            {
                _flowNode.dbOper = base.dbOper;
                base.dbOper.BeginTrans();
                FlowLineBO line = new FlowLineBO(base.dbOper);
                line.DeleteByNodeID(id);


                base.Delete(id);

                base.dbOper.CommitTrans();
            }
            catch(Exception ex)
            {
                base.dbOper.RollbackTrans();
                throw ex;
            }          
            
        }

        public List<FlowNodeInfo> GetList(int flowID)
        {
            List<FlowNodeInfo> list = _flowNode.GetList(flowID);
            foreach (FlowNodeInfo info in list)
            {
                SetDelegate(info);
            }
            return list;
        }

        /// <summary>
        /// 获取一个用户在一个流程当中可能审批的节点
        /// </summary>
        /// <param name="flowID"></param>
        /// <param name="userID"></param>
        /// <returns></returns>
        public List<FlowNodeInfo> GetList(int flowID, int userID)
        {
            List<FlowNodeInfo> list = _flowNode.GetList(flowID, userID);
            SetDelegate(list);
            return list;
        }

        public DataTable GetDataTable(int flowID)
        {
            DataTable dt = _flowNode.GetDataTable(flowID);
        
            return dt;
        }

        public DataTable GetDataTable(int flowID, string controlName)
        {
            DataTable dt = GetDataTable(flowID);

            List<EnumInfo> rightName = ConvertUtil.ConvertEnum(typeof(RightName));
            foreach (EnumInfo info in rightName)
            {
                dt.Columns.Add(info.Name + "ID");
                dt.Columns.Add(info.Name);
            }

            ControlRightBO right = new ControlRightBO();
            List<ControlRightInfo> rightList = right.GetList(flowID, controlName);
            ;
            //未完
            UserBO user = new UserBO();
            List<UserInfo> userList = user.GetList(rightList.Select(T => T.UserID));

            foreach (DataRow row in dt.Rows)
            {
                //给各列加上数据
                foreach (EnumInfo info in rightName)
                {
                    IEnumerable<int> userIDs = from tmp in rightList
                                               where tmp.RightID == info.ID && tmp.NodeID == (int)row["ID"] && tmp.ControlName == controlName
                                               select tmp.UserID;
                    row[info.Name + "ID"] = StrUtil.MergeToStr(userIDs, ",");
                    IEnumerable<string> userNames = from tmp in userList
                                                    where userIDs.Contains(tmp.ID)
                                                    select tmp.Name;
                    row[info.Name] = StrUtil.MergeToStr(userNames, ",");
                }
            }

            return dt;
        }

        public override FlowNodeInfo GetInfo(object id)
        {
            FlowNodeInfo info = base.GetInfo(id);
            if (id != null)
            {
                SetDelegate(info);                
            }
            return info;

        }

        private void SetDelegate(FlowNodeInfo info)
        {
            info.GetUserIDs = id => _flowNode.GetUserIDs(id);
            info.GetRoleIDs = id => _flowNode.GetRoleIDs(id);
            info.GetNextInfos = id => GetNextNodes(id);
            info.GetAllUserIDs = id => GetAllUserIDs(id);
            info.GetFromLines = id => _flowNode.GetFromLines(id);
            info.GetToLines = id => _flowNode.GetToLines(id);
        }



        private void SetDelegate(List<FlowNodeInfo> nodes)
        {
            foreach (FlowNodeInfo info in nodes)
            {
                SetDelegate(info);
            }
        }

        public override void Save(FlowNodeInfo info)
        {
            base.Save(info);

            _flowNode.SaveUserIDs(info.UserIDs, info.ID);
            _flowNode.SaveRoleIDs(info.RoleIDs, info.ID);
        }

        public void SavePosition(int id, double left, double top)
        {
            _flowNode.SavePosition(id, left, top);
        }

        public List<FlowNodeInfo> GetNextNodes(object id)
        {
            if (id == null)
            {
                return null;
            }
            else
            {
                List<FlowNodeInfo> nodes = _flowNode.GetNextNodes(id);
                foreach (FlowNodeInfo info in nodes)
                {
                    SetDelegate(info);
                }
                return nodes;
            }
        }

        /// <summary>
        /// 这个节点的所有用户，包括角色里的用户
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public List<UserInfo> GetAllUsers(object id)
        {
            List<int> userIDs = GetAllUserIDs(id);
            UserBO user = new UserBO();
            List<UserInfo> list = user.GetList(userIDs);
            return list;
            
        }

        private List<int> GetAllUserIDs(object id)
        {
            List<int> roleIDs = _flowNode.GetRoleIDs(id);
            List<int> userIDs = _flowNode.GetUserIDs(id);
            RoleBO role = new RoleBO();
            CommUtil.MergeList<int>(userIDs, role.GetUserIDs(roleIDs));

            return userIDs;
        }
    }
}
